package com.milkcoffee.designpatterns.singleton;

/**
 * @author zxs
 */
public class LazySingleton {

    // 使用volatile防止重排序
    private volatile static LazySingleton singleton;

    private LazySingleton(){

    }

    /**
     * 优化一：
     * 在方法上加synchronized 但是这个的并发非常低串行执行
     */
    public static LazySingleton getInstance(){
        if (singleton == null){
            /**
             * 优化二：降低锁的粒度，但是存在问题当两个线程都进去的时候会实例化两次
             */
            synchronized (LazySingleton.class){
                /**
                 * 优化三：当后面线程进来的时候首先会先判断当前对象是否已经被初始化过
                 */
                if (singleton == null){
                    /**
                     * 优化四：在这里会出现指令的重排序,出现如下的情况
                     * 正常流程：
                     * 1.分配内存空间
                     * 2.将数据初始化到分配的内存中
                     * 3.将对象指向初始化好的数据
                     *
                     * JIT在编译的时候会出现的指令的重排
                     * 异常流程(指令重排):
                     * 1.分配内存空间
                     * 2.将对象指向已经分配的内存空间
                     * 3.初始化
                     */
                    singleton = new LazySingleton();
                }
            }
        }

        return singleton;
    }
}
